/************************************************************************
 *
 * stdarg.h
 *
 * (c) Copyright 1996-2004 Analog Devices, Inc.  All rights reserved.
 * $Revision: 6 $
 ************************************************************************/

#pragma once
#ifndef __NO_BUILTIN
#pragma system_header /* stdarg.h */
#endif

#ifndef __STDARG_DEFINED
#define __STDARG_DEFINED

#ifndef _YVALS
 #include <yvals.h>
#endif

#if !defined(__VA_LIST_DEFINED) && !defined(_VA_LIST_DEFINED)
  #define __VA_LIST_DEFINED
  #define _VA_LIST_DEFINED
  typedef char *va_list;
#endif

/* In TigerSharc, scalar arguments are naturally aligned, i.e. the
 * address must be evenly divisible by the size. Structure arguments
 * are not naturally aligned, but instead are aligned according to the
 * constituent scalar field with the strictest alignment requirement.
 * Thus the alignment of an argument cannot be deduced from only its
 * size, since this would not work for struct arguments.
 */
/* The offset of field <m> in struct <s> */
#define __VA_OFFSETOF(s,m) (unsigned long)&(((s*)(void*)0)->m)

/* The alignment requirement of type <t> is obtained as the offset
 * of a field of that type following a char field in a struct. This
 * assumes that structs are laid out with "holes" of the minimum
 * size necessary to obtain proper alignment of fields. This macro
 * returns 0 for any alignment, 1 for even alignment, 3 for quad
 * alignment, so on.
 */
#if defined(__cplusplus) || defined(__ANALOG_EXTENDED_C__)
  extern "C++" {
    template <class T>
    struct __va_struct {
      long i;
      T    s;
    };
  }
  #define __VA_ALIGN_OF(t) (__VA_OFFSETOF(__va_struct<t>,s)-1)
#else
  #define __VA_ALIGN_OF(t) (__VA_OFFSETOF(struct{long i;t s;},s)-1)
#endif

/* The pointer to the next arg <ap> is adjusted to account for the
 * alignment requirement of the next argument, which has type <t>.
 */
#define __VA_ADJUST(ap,t) \
  (ap=(va_list)(((unsigned long)ap+__VA_ALIGN_OF(t))&~__VA_ALIGN_OF(t)))

#define va_start(ap,v) (void)((ap) = (va_list)__builtin_va_start(&(v), sizeof(v)))
#define va_arg(ap,t) (((t*)(__VA_ADJUST(ap,t),ap+=sizeof(t)))[-1])
#define va_end(ap) (void)((ap) = 0)

#endif  /* __STDARG_DEFINED */
